#include "BaseWindow.h"

const TCHAR* BaseWindow::CLASS_NAME = L"JurkowskimWindow";
const TCHAR* BaseWindow::MSG_NAME = L"MsgJurkowskimWindow";

BaseWindow* single = NULL;

void BaseWindow::CreateWndClass(HICON hIcon) {
	WNDCLASSEX wcx;
	wcx.cbSize = sizeof(WNDCLASSEX);
	wcx.style = CS_DBLCLKS;
	wcx.cbClsExtra = 0;
	wcx.cbWndExtra = 0;
	wcx.hInstance = hInst;
	wcx.hIcon = hIcon;
	wcx.hCursor = LoadCursor(0, IDC_ARROW);
	wcx.hbrBackground = 0;
	wcx.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
	wcx.hIconSm = 0;
	wcx.lpszClassName = CLASS_NAME;
	wcx.lpfnWndProc = &WndProc;

	RegisterClassEx(&wcx);
}

DWORD BaseWindow::GetWindowStyle() {
	if(fullScreen)
		return WS_POPUP | WS_SYSMENU | WS_VISIBLE;
	else 
		return (WS_OVERLAPPED | WS_MINIMIZEBOX | 
			WS_THICKFRAME | WS_MAXIMIZEBOX |
			WS_CAPTION | WS_SYSMENU | WS_VISIBLE);
}

void BaseWindow::CreateWnd() {
	DWORD style = GetWindowStyle();
	RECT rc = {0, 0, wndWidth, wndHeight};
	AdjustWindowRectEx(&rc, style, true, WS_EX_COMPOSITED);	

	hWnd = CreateWindowEx(WS_EX_COMPOSITED, CLASS_NAME,
				L"PathFinder", style, CW_USEDEFAULT, 
				CW_USEDEFAULT, rc.right - rc.left, 
				rc.bottom - rc.top, 0, 0, hInst, 0);
	//hWnd2 = CreateDialog(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, &WndProc2);
	//ShowWindow(hWnd2, SW_SHOW);
	OnInit();

	//hTools = CreateToolBar();
	//ShowWindow(hWnd, SW_SHOW);
	//UpdateWindow(hWnd);
}

int BaseWindow::Run() {
	MSG msg; 
	msg.message = WM_NULL;

	while(msg.message != WM_QUIT) {
		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
			if (!IsDialogMessage(hWnd2, &msg)) {
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		} else {
			if(this->activate) {
				Draw();
				SwapBuffers(hDC);
			}
		}
	}
	return static_cast<int> (msg.wParam);
}

void CALLBACK BaseWindow::TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) {
	//return single->OnTimer(hwnd, uMsg, idEvent, dwTime);
	single->OnTimerMethod();
}

LRESULT CALLBACK BaseWindow::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	return single->OnWndProc(hWnd, msg, wParam, lParam);
}

LRESULT BaseWindow::OnWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	POINT pp;
	switch(msg) {
	case WM_KEYDOWN:
 		OnKeyDown(wParam);
		break;
	case WM_LBUTTONDOWN:
		OnLButtonDown(wParam, lParam);
		break;
	case WM_COMMAND:
		OnMenuChoosed(wParam);
		break;
	case WM_RBUTTONDOWN:	
		if((wParam & MK_CONTROL) != 0) {
			point = MAKEPOINTS(lParam);
		} else 
			OnRButtonDown(wParam, lParam);
		break;
	case WM_MOUSEWHEEL:		
		OnMouseWheel(wParam, lParam);
		break;
	case WM_RBUTTONUP:
		OnRButtonUp(wParam, lParam);
		break;
	case WM_LBUTTONUP:		
		break;
	case WM_MOUSEMOVE:
		if( ((wParam & MK_CONTROL) != 0) && ((wParam & MK_RBUTTON) != 0) ) {
			pp.x = LOWORD(lParam);
			pp.y = HIWORD(lParam);
			ClientToScreen(hWnd, &pp);
			SetWindowPos(hWnd, HWND_TOPMOST, pp.x - point.x , pp.y - point.y , 0, 0, SWP_NOSIZE);
		}		
		OnMouseMove(wParam, lParam);
		break;
	case WM_SYSCOMMAND:
		switch (wParam)
		{
			case SC_SCREENSAVE:
			case SC_MONITORPOWER:
			return 0;
		}
		break;
	case WM_ACTIVATE:
		if (!HIWORD(wParam))
			this->activate = true;			
		else
			this->activate = false;
		return 0;
	case WM_ERASEBKGND:
		break;
	case WM_PAINT:
		//Draw();
		break;
	case WM_ENTERSIZEMOVE:
		return 0;
		break;
	case WM_CREATE:
		break;
	//case WM_WINDOWPOSCHANGED:
	//case WM_EXITSIZEMOVE:
	case WM_SIZE:
		ResizeWindow();
		SizeChanged();		
		break;
	case WM_DESTROY:
		OnDestroy();
		PostQuitMessage(0);
		break;
	default:
		break;
	}

	return DefWindowProc(hWnd, msg, wParam, lParam);
}

BOOL CALLBACK BaseWindow::WndProc2(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	return single->OnWndProc2(hWnd, msg, wParam, lParam);
}

BOOL BaseWindow::OnWndProc2(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	switch(msg) {
	case WM_ACTIVATE:
		return 0;
	case WM_ERASEBKGND:
		break;
	case WM_PAINT:
		break;
	case WM_DESTROY:
		//OnDestroy2();
		PostQuitMessage(0);
		break;
	default:
		break;
	}

	return DefWindowProc(hWnd, msg, wParam, lParam);
}

void BaseWindow::ResizeWindow() {
	RECT rc;
	GetClientRect(hWnd, &rc);
	wndWidth = static_cast<UINT>(rc.right - rc.left);
	wndHeight = static_cast<UINT>(rc.bottom - rc.top);
	if(hTools)
		SetWindowPos(hTools, HWND_TOPMOST, 0, 0, 
			rc.right-rc.left, toolHeight, SWP_SHOWWINDOW);
}

BaseWindow::BaseWindow(HINSTANCE hInst) {

	if(single == NULL)
		single = this;

	this->activate = true;
	this->fullScreen = false;
	this->wndHeight = 600;
	this->wndWidth = 800;
	this->toolHeight = 0;
	this->hInst = hInst;
	this->hWnd = NULL;
	this->hDC = NULL;
	this->hRC = NULL;
	this->hTools = NULL;
	this->hToolBmp = NULL;
}

BaseWindow::~BaseWindow() {
	if(hToolBmp)
		DeleteObject(hToolBmp);
	if(!UnregisterClass(CLASS_NAME, hInst)) {
		MessageBox(NULL, L"Could Not Unregister Class.",
			L"SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
		hInst=NULL;				
	}
}

int BaseWindow::Go(HICON hicon) {
	INITCOMMONCONTROLSEX icsex;
	icsex.dwSize = sizeof(INITCOMMONCONTROLSEX);
	icsex.dwICC = ICC_COOL_CLASSES|ICC_BAR_CLASSES;
	InitCommonControlsEx(&icsex);
	
	this->CreateWndClass(hicon);
	this->CreateWnd();
	this->OnCreate();
	return this->Run();
}

void BaseWindow::Exit() {
	//DestroyWindow(hWnd2);
	PostMessage(hWnd, WM_CLOSE, 0, 0);
}
/*
HWND BaseWindow::CreateToolBar() {
	HWND hReBar = CreateWindowEx(WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS
		| WS_BORDER | WS_CLIPCHILDREN | RBS_VARHEIGHT | RBS_BANDBORDERS, 0, 0, 0, 0, hWnd, NULL, hInst, NULL);

	REBARBANDINFO rbbi;
	rbbi.cbSize = sizeof(REBARBANDINFO);
	rbbi.fMask = RBBIM_TEXT | RBBIM_BACKGROUND | RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE;
	rbbi.fStyle = RBBS_CHILDEDGE | RBBS_FIXEDBMP | RBBS_GRIPPERALWAYS;
	rbbi.hbmBack = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_TLOSZARE));

	TBBUTTON tbb[9];

	ZeroMemory(tbb, sizeof(tbb));
	for(int i=0; i<9; ++i) {
		tbb[i].idCommand = i;
		tbb[i].fsState = TBSTATE_ENABLED;
		tbb[i].fsStyle = TBSTYLE_BUTTON;
	}
	tbb[0].iBitmap = 0;
	tbb[1].iBitmap = 1;
	tbb[2].iBitmap = 0; tbb[2].fsStyle = TBSTYLE_SEP;
	tbb[3].iBitmap = 2;
	tbb[4].iBitmap = 3;
	tbb[5].iBitmap = 4;
	tbb[6].iBitmap = 5;
	tbb[7].iBitmap = 0; tbb[7].fsStyle = TBSTYLE_SEP;
	tbb[8].iBitmap = 6;

	hToolBmp = (HBITMAP)LoadImage(hInst, MAKEINTRESOURCE(IDB_TOOLS), IMAGE_BITMAP, 
		0, 0, LR_LOADTRANSPARENT);
	
	HWND toolBar = CreateToolbarEx(hReBar, WS_CHILD | WS_VISIBLE | CCS_NOPARENTALIGN
		| CCS_NODIVIDER | TBSTYLE_FLAT, IDR_TOOLBAR, TOOLS_NUMBER, NULL, (UINT) hToolBmp, 
		tbb, 9, 24, 24, 24, 24, sizeof(TBBUTTON));

	rbbi.lpText = L"";
	rbbi.hwndChild = toolBar;
	rbbi.cxMinChild = 100;
	rbbi.cyMinChild = 28;
	rbbi.cx = 100;	
	SendMessage(hReBar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbbi);

	RECT rc;
	GetWindowRect(hReBar, &rc);
	toolHeight = rc.bottom - rc.top;
	return hReBar;
}
*/